import re

import openpyxl
from rest_framework import status
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, UpdateModelMixin, ListModelMixin, \
    RetrieveModelMixin
from rest_framework_simplejwt.exceptions import TokenError, InvalidToken
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView

from common.exportFile import export_excel
from common.permissions import MyPermission
from users.models import UserProfile
from users.serializers import UserProfileSerializer, UserProfileDetailSerializer, UserProfileUpdateSerializer


class LoginView(TokenObtainPairView):
    def post(self, request: Request, *args, **kwargs) -> Response:
        serializer = self.get_serializer(data=request.data)

        try:
            serializer.is_valid(raise_exception=True)
        except TokenError as e:
            raise InvalidToken(e.args[0])

        res = serializer.validated_data
        res['id'] = serializer.user.id
        res['username'] = serializer.user.username
        res['mobile'] = serializer.user.mobile
        res['email'] = serializer.user.email
        res['token'] = res.pop('access')
        res['permissions_list'] = serializer.user.get_all_permissions()

        return Response({'msg': '登录成功', 'data': res}, status=status.HTTP_200_OK)


class UserView(GenericViewSet, CreateModelMixin, ListModelMixin):
    queryset = UserProfile.objects.all().order_by('-create_time')
    serializer_class = UserProfileSerializer


class UserDetailView(GenericViewSet, DestroyModelMixin, UpdateModelMixin, RetrieveModelMixin):
    queryset = UserProfile.objects.all()
    serializer_class = UserProfileDetailSerializer

    def update(self, request, *args, **kwargs):
        custom_serializer_class = UserProfileUpdateSerializer
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = custom_serializer_class(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)
        return Response(serializer.data)


class UserResetView(APIView):

    def get(self, request: Request, pk):
        user = UserProfile.objects.get(id=pk)
        if not user:
            return Response({'msg': '用户不存在'}, status=status.HTTP_400_BAD_REQUEST)
        user.set_password('666666')
        user.save()
        return Response({'msg': '密码重置成功'}, status=status.HTTP_200_OK)


class UserExportView(APIView):

    def post(self, request: Request):
        ids = request.data.get('ids', None)
        if ids and isinstance(ids, list):
            return Response({'msg': 'ids参数存在时为列表！'}, status=status.HTTP_400_BAD_REQUEST)
        if ids:
            user_list = UserProfile.objects.filter(id__in=ids)
        else:
            user_list = UserProfile.objects.all()
        serializer = UserProfileSerializer(user_list, many=True)
        serialized_users = serializer.data
        result = export_excel(serialized_users)
        return result


class UserUploadView(APIView):

    def post(self, request):
        file = request.data.get('file')
        if not file:
            return Response({'msg': '文件为空！'}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)
        # 检查文件类型是否为 Excel
        if not file.name.endswith(('.xls', '.xlsx')):
            return Response({'msg': '文件格式错误'}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)
        if file.size > 1024 * 1024 * 5:
            return Response({'msg': '文件大小不能超过5MB！'}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)

        # 读取 Excel 文件
        wb = openpyxl.load_workbook(file.file)
        ws = wb.active

        # 遍历 Excel 表格的每一行数据并保存到数据库中
        for row in ws.iter_rows(min_row=2, values_only=True):  # Assuming first row is header
            try:
                username, nick_name, phone, password = row
                # 数据校验
                if not username or not password:
                    raise ValueError('姓名和密码不能为空！')
                if UserProfile.objects.filter(username=username).exists():
                    raise ValueError('用户已存在！')
                if not re.match(r'^1[3-9]\d{9}$', str(phone)):
                    raise ValueError('手机号码格式错误！')
                if UserProfile.objects.filter(mobile=phone).exists():
                    raise ValueError('手机号码已经存在了！')

                # 将有效数据保存到数据库中，这里假设有一个数据库操作函数 save_user()
                UserProfile.objects.create_user(username=username, nick_name=nick_name, mobile=phone,
                                                password=str(password))
            except ValueError as e:
                print(f"数据导入失败：{e}")
        return Response({'msg': '上传成功'}, status=status.HTTP_200_OK)
